Flutter GPUSurfaceGL

GPUSurfaceGL 类是对 Flutter SurfaceOpenGL 下的实现。该类位于 src/flutter/shell/gpu/gpu_surface_gl.h


MakeGLContext

在该方法中,调用 skia 的初始化,创建出 OpenGL 下的 GrDirectContext

sk_sp<GrDirectContext> GPUSurfaceGL::MakeGLContext(GPUSurfaceGLDelegate* delegate) {
    auto context_switch = delegate->GLContextMakeCurrent();
    // ...

    const auto options =
        MakeDefaultContextOptionskRender, GrBackendApi::kOpenGL;

    auto context = GrDirectContext::MakeGL(delegate->GetGLInterface(), options);
	// ...

    context->setResourceCacheLimits(kGrCacheMaxCount, kGrCacheMaxByteSize);
	// ...

    return context;
}

Skia 通过 GrDirectContext 类管理 GPU,有了 GrDirectContext,就能够用它创建 SkSurface 等绘制对象了。

谁调用 MakeGLContext?

GPUSurfaceGL 的构造函数:

GPUSurfaceGL::GPUSurfaceGL(GPUSurfaceGLDelegate* delegate,
                           bool render_to_surface)
    : GPUSurfaceGL(MakeGLContext(delegate), delegate, render_to_surface) {
  context_owner_ = true;
}

在 AndroidSurfaceGL 中,有一个 CreateGPUSurface 方法,如果传入的 GrDirectContext 为空,则会调用这里的方法创建一个:

std::unique_ptr<Surface> AndroidSurfaceGL::CreateGPUSurface(
    GrDirectContext* gr_context) {
  if (gr_context) {
    return std::make_unique<GPUSurfaceGL>(sk_ref_sp(gr_context), this, true);
  } else {
    sk_sp<GrDirectContext> main_skia_context =
        GLContextPtr()->GetMainSkiaContext();
    if (!main_skia_context) {
      main_skia_context = GPUSurfaceGL::MakeGLContext(this);
      GLContextPtr()->SetMainSkiaContext(main_skia_context);
    }
    return std::make_unique<GPUSurfaceGL>(main_skia_context, this, true);
  }
}

构造方法

GPUSurfaceGL 拥有两个构造方法,区别在于 GrDirectContext 是否由自己创建,并且使用 context_owner_ 成员标量表征是否是自己创建的。

GPUSurfaceGL::GPUSurfaceGL(GPUSurfaceGLDelegate* delegate,
                           bool render_to_surface)
	// 创建 `GrDirectContext` 对象
	// 调用第二个构造函数
    : GPUSurfaceGL(MakeGLContext(delegate), delegate, render_to_surface) {
  context_owner_ = true;
}

GPUSurfaceGL::GPUSurfaceGL(sk_sp<GrDirectContext> gr_context,
                           GPUSurfaceGLDelegate* delegate,
                           bool render_to_surface)
    : delegate_(delegate),
      context_(gr_context),
      context_owner_(false),
      render_to_surface_(render_to_surface),
      weak_factory_(this) {
  // 尝试将OpenGL上下文切换到delegate_
  auto context_switch = delegate_->GLContextMakeCurrent();
  // 检查切换是否成功
  if (!context_switch->GetResult()) {
    FML_LOG(ERROR)
        << "Could not make the context current to set up the Gr context.";
    return;
  }

  delegate_->GLContextClearCurrent();

  // 表示这个 GPUSurfaceGL 是否有效
  valid_ = gr_context != nullptr;
}

其中:GLContextMakeCurrent 到 GLContextClearCurrent 的作用是:

GLContextMakeCurrentGLContextClearCurrent的调用是为了在设置GrDirectContext(即gr_context)时,确保正确的OpenGL上下文是当前活动的。

GLContextMakeCurrent的调用是为了将OpenGL上下文切换到delegate_。这是因为在设置GrDirectContext时,需要确保正确的OpenGL上下文是当前活动的。如果不这样做,可能会在错误的上下文中设置GrDirectContext,导致渲染错误。

然后,代码检查上下文切换是否成功。如果上下文切换失败,那么就记录一条错误日志并返回,不再执行后续的代码。

如果上下文切换成功,那么就调用GLContextClearCurrent来清除当前的OpenGL上下文。这是因为在设置完GrDirectContext后,不再需要OpenGL上下文,所以将其清除以防止后续的代码错误地使用这个上下文。

总的来说,GLContextMakeCurrentGLContextClearCurrent的调用是为了确保在设置GrDirectContext时,正确的OpenGL上下文是当前活动的,并在设置完GrDirectContext后,清除当前的OpenGL上下文。


本文作者:Maeiee

本文链接:Flutter GPUSurfaceGL

版权声明:如无特别声明,本文即为原创文章,版权归 Maeiee 所有,未经允许不得转载!


喜欢我文章的朋友请随缘打赏,鼓励我创作更多更好的作品!